home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / sd-26.zip / sd12.c < prev    next >
C/C++ Source or Header  |  1992-09-09  |  15KB  |  444 lines

  1. /* SD -- square dance caller's helper.
  2.  
  3.     Copyright (C) 1990, 1991, 1992  William B. Ackerman.
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 1, or (at your option)
  8.     any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19.     This is version 24.0. */
  20.  
  21. /* This defines the following functions:
  22.    triangle_move
  23. */
  24.  
  25. #include "sd.h"
  26.  
  27.  
  28. static void ctr_end_triangle_move(
  29.    setup *s,
  30.    parse_block *parseptr,
  31.    setup *result)
  32.  
  33. {
  34.    calldef_schema schema;
  35.  
  36.    if (parseptr->concept->value.arg1 == 2) {
  37.       switch (s->kind) {
  38.          case s_hrglass:
  39.             schema = schema_vertical_6;   /* This is the schema for picking out
  40.                                              the triangles in an hourglass. */
  41.             break;
  42.          case s_rigger:
  43.             schema = schema_concentric_6_2;
  44.             break;
  45.          case s_ptpd:
  46.             schema = schema_concentric_6_2;
  47.             break;
  48.          default:
  49.             fail("There are no 'inside' triangles.");
  50.       }
  51.  
  52.       concentric_move(s, parseptr->next, (parse_block *) 0, NULLCALLSPEC, NULLCALLSPEC, 0, 0,
  53.                schema, 0, 0, result);
  54.    }
  55.    else {
  56.       switch (s->kind) {
  57.          case s_ptpd:
  58.             schema = schema_concentric_2_6;
  59.             break;
  60.          case s_spindle: case s_bone:
  61.             schema = schema_concentric_2_6;
  62.             break;
  63.          default:
  64.             fail("There are no 'outside' triangles.");
  65.       }
  66.  
  67.       concentric_move(s, (parse_block *) 0, parseptr->next, NULLCALLSPEC, NULLCALLSPEC, 0, 0,
  68.                schema, 0, 0, result);
  69.    }
  70. }
  71.  
  72.  
  73. typedef struct qwerty {
  74.    int mapqt1[3];   /* First triangle (upright) in quarter-tag. */
  75.    int mapqt2[3];   /* Second triangle (inverted) in quarter-tag. */
  76.    int mapqti[2];   /* Idle people in quarter-tag. */
  77.    int mapcp1[3];   /* First triangle (inverted) in C1 phantom. */
  78.    int mapcp2[3];   /* Second triangle (upright) in C1 phantom. */
  79.    int mapcpi[2];   /* Idle people in C1 phantom. */
  80.    int map241[3];   /* First triangle (inverted) in 2x4. */
  81.    int map242[3];   /* Second triangle (upright) in 2x4. */
  82.    int map24i[2];   /* Idle people in 2x4. */
  83.    setup_kind kind;
  84.    struct qwerty *other;
  85.    } tgl_map;
  86.  
  87. /* These need to be external so that they can refer to each other. */
  88. extern tgl_map map1b;
  89. extern tgl_map map2b;
  90.  
  91. /*                 mapqt1     mapqt2   mapqti    mapcp1        mapcp2      mapcpi    map241     map242   map24i   kind     other */
  92. tgl_map map1b = {{4, 3, 2}, {0, 7, 6}, {1, 5}, {6,  8, 10}, {14,  0,  2}, {4, 12}, {6, 5, 4}, {2, 1, 0}, {3, 7}, s_c1phan, &map2b};
  93. tgl_map map2b = {{5, 6, 7}, {1, 2, 3}, {0, 4}, {3, 15, 13}, {11,  7,  5}, {1,  9}, {7, 6, 5}, {3, 2, 1}, {0, 4}, s_qtag,   &map1b};
  94.  
  95.  
  96. static void do_glorious_triangles(
  97.    setup *s,
  98.    setup *a1,
  99.    setup *a2,
  100.    setup *idle,
  101.    int startingrot,
  102.    tgl_map *map_ptr,
  103.    parse_block *parseptr,
  104.    setup *result)
  105.  
  106. {
  107.    int i, r;
  108.    setup res1, res2;
  109.  
  110.    a1->kind = s_trngl;
  111.    a2->kind = s_trngl;
  112.    a1->rotation = startingrot;
  113.    a2->rotation = startingrot;
  114.    a1->setupflags = s->setupflags | SETUPFLAG__DISTORTED;
  115.    a2->setupflags = s->setupflags | SETUPFLAG__DISTORTED;
  116.    move(a1, parseptr, NULLCALLSPEC, 0, FALSE, &res1);
  117.    move(a2, parseptr, NULLCALLSPEC, 0, FALSE, &res2);
  118.  
  119.    if (res1.kind != res2.kind || res1.rotation != res2.rotation)
  120.       fail("Improper result from triangle call.");
  121.  
  122.    res1.rotation &= 3;     /* Just making sure. */
  123.  
  124.    result->rotation = res1.rotation;
  125.  
  126.    r = ((-res1.rotation) & 3) * 011;
  127.  
  128.    if (res1.kind == s_trngl) {
  129.       if (res1.rotation & 2)
  130.          result->kind = map_ptr->other->kind;
  131.       else
  132.          result->kind = map_ptr->kind;
  133.    
  134.       if (res1.rotation == 0) {
  135.          result->kind = s_qtag;
  136.          /* Restore the two people who don't move. */
  137.          (void) copy_person(result, map_ptr->mapqti[0], idle, 0);
  138.          (void) copy_person(result, map_ptr->mapqti[1], idle, 1);
  139.    
  140.          for (i=0; i<3; i++) {
  141.             (void) copy_person(result, map_ptr->mapqt1[i], &res1, i);
  142.             (void) copy_rot(result, map_ptr->mapqt2[i], &res2, i, 022);
  143.          }
  144.       }
  145.       else if (res1.rotation == 2) {
  146.          result->kind = s_c1phan;
  147.          /* Restore the two people who don't move. */
  148.          (void) copy_rot(result, map_ptr->mapcpi[1], idle, 0, r);
  149.          (void) copy_rot(result, map_ptr->mapcpi[0], idle, 1, r);
  150.          
  151.          for (i=0; i<3; i++) {
  152.             (void) copy_person(result, map_ptr->mapcp2[i], &res1, i);
  153.             (void) copy_rot(result, map_ptr->mapcp1[i], &res2, i, 022);
  154.          }
  155.       }
  156.       else {
  157.          if (result->kind == s_c1phan) {
  158.              /* Restore the two people who don't move. */
  159.              (void) copy_rot(result, map_ptr->other->mapcpi[0], idle, 0, r);
  160.              (void) copy_rot(result, map_ptr->other->mapcpi[1], idle, 1, r);
  161.    
  162.              /* Copy the triangles. */
  163.              for (i=0; i<3; i++) {
  164.                 (void) copy_person(result, map_ptr->other->mapcp2[i], &res1, i);
  165.                 (void) copy_rot(result, map_ptr->other->mapcp1[i], &res2, i, 022);
  166.              }
  167.          }
  168.          else {
  169.              /* Restore the two people who don't move. */
  170.              (void) copy_rot(result, map_ptr->other->mapqti[1], idle, 0, r);
  171.              (void) copy_rot(result, map_ptr->other->mapqti[0], idle, 1, r);
  172.    
  173.              /* Copy the triangles. */
  174.              for (i=0; i<3; i++) {
  175.                 (void) copy_person(result, map_ptr->other->mapqt1[i], &res1, i);
  176.                 (void) copy_rot(result, map_ptr->other->mapqt2[i], &res2, i, 022);
  177.              }
  178.          }
  179.       }
  180.    }
  181.    else if (res1.kind == s_1x3) {
  182.       result->kind = s2x4;
  183.  
  184.       if (res1.rotation == 0) {
  185.          (void) copy_person(result, map_ptr->map24i[0], idle, 0);
  186.          (void) copy_person(result, map_ptr->map24i[1], idle, 1);
  187.          for (i=0; i<3; i++) {
  188.             (void) copy_person(result, map_ptr->map241[i], &res1, i);
  189.             (void) copy_rot(result, map_ptr->map242[i], &res2, i, 022);
  190.          }
  191.       }
  192.       else {
  193.          if (map_ptr->kind == s_c1phan) {    /* What a crock! */
  194.             (void) copy_rot(result, map_ptr->other->map24i[0], idle, 0, r);
  195.             (void) copy_rot(result, map_ptr->other->map24i[1], idle, 1, r);
  196.             for (i=0; i<3; i++) {
  197.                (void) copy_person(result, map_ptr->other->map242[i], &res1, 2-i);
  198.                (void) copy_rot(result, map_ptr->other->map241[i], &res2, 2-i, 022);
  199.             }
  200.          }
  201.          else {
  202.             (void) copy_rot(result, map_ptr->other->map24i[1], idle, 0, r);
  203.             (void) copy_rot(result, map_ptr->other->map24i[0], idle, 1, r);
  204.             for (i=0; i<3; i++) {
  205.                (void) copy_person(result, map_ptr->other->map241[i], &res1, i);
  206.                (void) copy_rot(result, map_ptr->other->map242[i], &res2, i, 022);
  207.             }
  208.          }
  209.       }
  210.    }
  211.    else
  212.       fail("Improper result from triangle call.");
  213.  
  214.    if (result->kind == s2x4)
  215.        warn(warn__check_2x4);
  216.    else if (res1.rotation != startingrot) {
  217.       if (result->kind == s_c1phan)
  218.           warn(warn__check_c1_phan);
  219.       else
  220.           warn(warn__check_dmd_qtag);
  221.    }
  222.  
  223.    result->setupflags = res1.setupflags | res2.setupflags;
  224. }
  225.  
  226.  
  227.  
  228.  
  229. /* This procedure does wave-base, tandem-base, and so-and-so-base. */
  230. static void wv_tand_base_move(
  231.    setup *s,
  232.    parse_block *parseptr,
  233.    setup *result)
  234.  
  235. {
  236.    int i, t, tbonetest;
  237.    calldef_schema schema;
  238.    setup a1, a2;
  239.    setup idle;
  240.    tgl_map *map_ptr;
  241.  
  242.    switch (s->kind) {
  243.       case s_galaxy:
  244.          /* We allow so-and-so-base triangles only in C1 phantoms. */
  245.          if (parseptr->concept->value.arg1 == 20)
  246.             fail("Can't find the indicated triangles.");
  247.          tbonetest = s->people[1].id1 | s->people[3].id1 | s->people[5].id1 | s->people[7].id1;
  248.          if ((tbonetest & 011) == 011)
  249.             fail("Can't find the indicated triangles.");
  250.          else if ((parseptr->concept->value.arg1 ^ tbonetest) & 1)
  251.             schema = schema_lateral_6;
  252.          else
  253.             schema = schema_vertical_6;
  254.    
  255.          /* For galaxies, the schema is now in terms of the absolute orientation. */
  256.          /* We know that the original setup rotation was canonicalized. */
  257.          break;
  258.       case s_hrglass:
  259.          /* We allow so-and-so-base triangles only in C1 phantoms. */
  260.          if (parseptr->concept->value.arg1 == 20)
  261.             fail("Can't find the indicated triangles.");
  262.          tbonetest = s->people[0].id1 | s->people[1].id1 | s->people[4].id1 | s->people[5].id1;
  263.          if ((tbonetest & 011) == 011)
  264.             fail("Can't find the indicated triangles.");
  265.          else if ((parseptr->concept->value.arg1 ^ tbonetest) & 1)
  266.             fail("Can't find the indicated triangles.");
  267.    
  268.          schema = schema_vertical_6;   /* This is the schema for picking out
  269.                                           the triangles in an hourglass. */
  270.          break;
  271.       case s_c1phan:
  272.          if (parseptr->concept->value.arg1 == 20) {
  273.             t = 0;
  274.             if (global_selectmask == (global_livemask & 0x5A5A))
  275.                t = 1;
  276.             else if (global_selectmask != (global_livemask & 0xA5A5))
  277.                fail("Can't find the indicated triangles.");
  278.             parseptr = parseptr->next;           /* Skip over the selector. */
  279.          }
  280.          else {
  281.             t = parseptr->concept->value.arg1 & 1;
  282.             if ((global_tbonetest & 010) == 0) t ^= 1;
  283.             else if ((global_tbonetest & 1) != 0)
  284.                fail("Can't find the indicated triangles.");
  285.          }
  286.  
  287.          /* Now t is 0 to select the triangles whose bases are horizontally
  288.             aligned, and 1 for the vertically aligned bases. */
  289.  
  290.          s->rotation += t;   /* Just flip the setup around and recanonicalize. */
  291.          canonicalize_rotation(s);
  292.  
  293.          if ((global_livemask & 0xAAAA) == 0) {
  294.             map_ptr = &map1b;
  295.          }
  296.          else if ((global_livemask & 0x5555) == 0) {
  297.             map_ptr = &map2b;
  298.          }
  299.          else
  300.             fail("Can't find the indicated triangles.");
  301.  
  302.          for (i=0; i<3; i++) {
  303.             (void) copy_rot(&a1, i, s, map_ptr->mapcp1[i], 022);
  304.             (void) copy_person(&a2, i, s, map_ptr->mapcp2[i]);
  305.          }
  306.       
  307.          /* Save the two people who don't move. */
  308.          (void) copy_person(&idle, 0, s, map_ptr->mapcpi[0]);
  309.          (void) copy_person(&idle, 1, s, map_ptr->mapcpi[1]);
  310.       
  311.          do_glorious_triangles(s, &a1, &a2, &idle, 2, map_ptr, parseptr->next, result);
  312.          result->rotation -= t;   /* Flip the setup back. */
  313.          reinstate_rotation(s, result);
  314.          return;
  315.       default:
  316.          fail("Can't do this concept in this setup.");
  317.    }
  318.  
  319.    concentric_move(s, parseptr->next, (parse_block *) 0, NULLCALLSPEC, NULLCALLSPEC, 0, 0,
  320.             schema, 0, 0, result);
  321. }
  322.  
  323.  
  324. static void tall_short_6_move(
  325.    setup *s,
  326.    parse_block *parseptr,
  327.    setup *result)
  328.  
  329. {
  330.    int tbonetest;
  331.    calldef_schema schema;
  332.  
  333.    if (s->kind == s_galaxy) {
  334.       /* We know the setup rotation is canonicalized. */
  335.       tbonetest = s->people[1].id1 | s->people[3].id1 | s->people[5].id1 | s->people[7].id1;
  336.  
  337.       if ((tbonetest & 011) == 011) fail("Can't find tall/short 6.");
  338.       else if ((parseptr->concept->value.arg1 ^ tbonetest) & 1)
  339.          schema = schema_lateral_6;
  340.       else
  341.          schema = schema_vertical_6;
  342.    }
  343.    else
  344.       fail("Must have galaxy for this concept.");
  345.  
  346.    /* For galaxies, the schema is now in terms of the absolute orientation. */
  347.  
  348.    concentric_move(s, parseptr->next, (parse_block *) 0, NULLCALLSPEC, NULLCALLSPEC, 0, 0,
  349.             schema, 0, 0, result);
  350. }
  351.  
  352.  
  353. extern void triangle_move(
  354.    setup *s,
  355.    parse_block *parseptr,
  356.    setup *result)
  357.  
  358. {
  359.    int i;
  360.    setup a1, a2;
  361.    setup idle;
  362.    tgl_map *map_ptr;
  363.  
  364. /* arg1 = 0 - out point
  365.           1 - in point
  366.           2 - inside
  367.           3 - outside
  368.           4 - tall 6
  369.           5 - short 6
  370.           6 - wave-base
  371.           7 - tandem-base
  372.           20 - so-and-so-base
  373. */
  374.  
  375.    if (parseptr->concept->value.arg1 >= 6) {
  376.       /* Set this so we can do "peel and trail" without saying "triangle" again. */
  377.       s->setupflags |= SETUPFLAG__SAID_TRIANGLE;
  378.       wv_tand_base_move(s, parseptr, result);
  379.       return;
  380.    }
  381.    else if (parseptr->concept->value.arg1 >= 4) {
  382.       tall_short_6_move(s, parseptr, result);
  383.       return;
  384.    }
  385.    else if (parseptr->concept->value.arg1 >= 2) {
  386.       /* Set this so we can do "peel and trail" without saying "triangle" again. */
  387.       s->setupflags |= SETUPFLAG__SAID_TRIANGLE;
  388.       ctr_end_triangle_move(s, parseptr, result);
  389.       return;
  390.    }
  391.  
  392.    /* arg1 = 1 for in point, 0 for out point */
  393.  
  394.    /* Set this so we can do "peel and trail" without saying "triangle" again. */
  395.    s->setupflags |= SETUPFLAG__SAID_TRIANGLE;
  396.  
  397.    if (s->kind != s_qtag) fail("Must have diamonds.");
  398.  
  399.    if (parseptr->concept->value.arg1) {
  400.       if (
  401.             (s->people[0].id1 & d_mask) == d_east &&
  402.             (s->people[1].id1 & d_mask) != d_west &&
  403.             (s->people[4].id1 & d_mask) == d_west &&
  404.             (s->people[5].id1 & d_mask) != d_east)
  405.          map_ptr = &map1b;
  406.       else if (
  407.             (s->people[0].id1 & d_mask) != d_east &&
  408.             (s->people[1].id1 & d_mask) == d_west &&
  409.             (s->people[4].id1 & d_mask) != d_west &&
  410.             (s->people[5].id1 & d_mask) == d_east)
  411.          map_ptr = &map2b;
  412.       else
  413.          fail("Can't find designated point.");
  414.    }
  415.    else {
  416.       if (
  417.             (s->people[0].id1 & d_mask) == d_west &&
  418.             (s->people[1].id1 & d_mask) != d_east &&
  419.             (s->people[4].id1 & d_mask) == d_east &&
  420.             (s->people[5].id1 & d_mask) != d_west)
  421.          map_ptr = &map1b;
  422.       else if (
  423.             (s->people[0].id1 & d_mask) != d_west &&
  424.             (s->people[1].id1 & d_mask) == d_east &&
  425.             (s->people[4].id1 & d_mask) != d_east &&
  426.             (s->people[5].id1 & d_mask) == d_west)
  427.          map_ptr = &map2b;
  428.       else
  429.          fail("Can't find designated point.");
  430.    }
  431.  
  432.    for (i=0; i<3; i++) {
  433.       (void) copy_person(&a1, i, s, map_ptr->mapqt1[i]);
  434.       (void) copy_rot(&a2, i, s, map_ptr->mapqt2[i], 022);
  435.    }
  436.  
  437.    /* Save the two people who don't move. */
  438.    (void) copy_person(&idle, 0, s, map_ptr->mapqti[0]);
  439.    (void) copy_person(&idle, 1, s, map_ptr->mapqti[1]);
  440.  
  441.    do_glorious_triangles(s, &a1, &a2, &idle, 0, map_ptr, parseptr->next, result);
  442.    reinstate_rotation(s, result);
  443. }
  444.